﻿// ===============================================================================
// Logger.cs
// EOS Framework
// ===============================================================================
// Copyright (c) EOS Development Group. All rights reserved.
// ===============================================================================

namespace EOS.Framework.Logger.Console
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using EOS.Framework.Contracts.Logger;
    using EOS.Framework.Tools.Aspects;

    /// <summary>
    /// Loogger implementation for logging to the console.
    /// </summary>
    [SuppressMessage("Microsoft.Naming", "CA1724")]
    public class ConsoleLogger : ILogger
    {
        private Type _consumerType;

        #region ILogger Members

        /// <summary>
        /// Initializes the logger with specified consumer type.
        /// </summary>
        /// <param name="consumerType">Type of the consumer. Cannot be null.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="consumerType"/> is
        /// null (Nothing in Visual Basic).</exception>
        [ParamNotNull("consumerType")]
        public void Initialize(Type consumerType)
        {
            _consumerType = consumerType;
        }

        /// <summary>
        /// Loggs a debug message by using the specified <see cref="T:System.IFormatProvider"/>.
        /// </summary>
        /// <param name="formatProvider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
        /// <param name="message">The debug message. Cannot be null or empty or contains only blanks.</param>
        /// <param name="args">A array of arguments.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="message"/> is null
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="message"/> is a string
        /// of length 0 or contains only blanks.</exception>
        /// <exception cref="T:System.InvalidOperationException">Logger is not initialized.</exception>
        [ParamNotNull("formatProvider"), ParamNotNullOrEmpty("message")]
        public void LogDebug(IFormatProvider formatProvider, string message, params string[] args)
        {
            DoLogging(formatProvider, "DEBUG", message, args);
        }

        /// <summary>
        /// Loggs a debug message.
        /// </summary>
        /// <param name="message">The debug message. Cannot be null or empty or contains only blanks.</param>
        /// <param name="args">A array of arguments.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="message"/> is null
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="message"/> is a string
        /// of length 0 or contains only blanks.</exception>
        /// <exception cref="T:System.InvalidOperationException">Logger is not initialized.</exception>
        [ParamNotNullOrEmpty("message")]
        public void LogDebug(string message, params object[] args)
        {
            DoLogging(null, "DEBUG", message, args);
        }

        /// <summary>
        /// Loggs a error message by using the specified <see cref="T:System.IFormatProvider"/>.
        /// </summary>
        /// <param name="formatProvider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
        /// <param name="message">The error message. Cannot be null or empty or contains only blanks.</param>
        /// <param name="args">A array of arguments.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="message"/> is null
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="message"/> is a string
        /// of length 0 or contains only blanks.</exception>
        /// <exception cref="T:System.InvalidOperationException">Logger is not initialized.</exception>
        [ParamNotNull("formatProvider"), ParamNotNullOrEmpty("message")]
        public void LogError(IFormatProvider formatProvider, string message, params string[] args)
        {
            DoLogging(formatProvider, "ERROR", message, args);
        }

        /// <summary>
        /// Loggs an error message.
        /// </summary>
        /// <param name="message">The error message. Cannot be null or empty or contains only blanks.</param>
        /// <param name="args">A array of arguments.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="message"/> is null
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="message"/> is a string
        /// of length 0 or contains only blanks.</exception>
        /// <exception cref="T:System.InvalidOperationException">Logger is not initialized.</exception>
        [ParamNotNullOrEmpty("message")]
        public void LogError(string message, params object[] args)
        {
            DoLogging(null, "ERROR", message, args);
        }

        /// <summary>
        /// Loggs a fatal error message by using the specified <see cref="T:System.IFormatProvider"/>.
        /// </summary>
        /// <param name="formatProvider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
        /// <param name="message">The fatal error message. Cannot be null or empty or contains only blanks.</param>
        /// <param name="args">A array of arguments.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="message"/> is null
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="message"/> is a string
        /// of length 0 or contains only blanks.</exception>
        /// <exception cref="T:System.InvalidOperationException">Logger is not initialized.</exception>
        [ParamNotNull("formatProvider"), ParamNotNullOrEmpty("message")]
        public void LogFatal(IFormatProvider formatProvider, string message, params string[] args)
        {
            DoLogging(formatProvider, "FATAL", message, args);
        }

        /// <summary>
        /// Loggs a fatal error message.
        /// </summary>
        /// <param name="message">The fatal error message. Cannot be null or empty or contains only blanks.</param>
        /// <param name="args">A array of arguments.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="message"/> is null
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="message"/> is a string
        /// of length 0 or contains only blanks.</exception>
        /// <exception cref="T:System.InvalidOperationException">Logger is not initialized.</exception>
        [ParamNotNullOrEmpty("message")]
        public void LogFatal(string message, params object[] args)
        {
            DoLogging(null, "FATAL", message, args);
        }

        /// <summary>
        /// Loggs a warning message by using the specified <see cref="T:System.IFormatProvider"/>.
        /// </summary>
        /// <param name="formatProvider">An <see cref="T:System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
        /// <param name="message">The warning message. Cannot be null or empty or contains only blanks.</param>
        /// <param name="args">A array of arguments.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="message"/> is null
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="message"/> is a string
        /// of length 0 or contains only blanks.</exception>
        /// <exception cref="T:System.InvalidOperationException">Logger is not initialized.</exception>
        [ParamNotNull("formatProvider"), ParamNotNullOrEmpty("message")]
        public void LogWarn(IFormatProvider formatProvider, string message, params string[] args)
        {
            DoLogging(formatProvider, "WARN", message, args);
        }

        /// <summary>
        /// Loggs a warning message.
        /// </summary>
        /// <param name="message">The warning message. Cannot be null or empty or contains only blanks.</param>
        /// <param name="args">A array of arguments.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="message"/> is null
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="T:System.ArgumentException"><paramref name="message"/> is a string
        /// of length 0 or contains only blanks.</exception>
        /// <exception cref="T:System.InvalidOperationException">Logger is not initialized.</exception>
        [ParamNotNullOrEmpty("message")]
        public void LogWarn(string message, params object[] args)
        {
            DoLogging(null, "WARN", message, args);
        }

        /// <summary>
        /// Does the logging.
        /// </summary>
        /// <param name="formatProvider">The format provider.</param>
        /// <param name="prefix">The prefix bevore the message.</param>
        /// <param name="message">The message.</param>
        /// <param name="args">An array of arguments.</param>
        private void DoLogging(IFormatProvider formatProvider, string prefix, string message, params object[] args)
        {
            string formattedMessage = null;

            IFormatProvider formatter = CultureInfo.CurrentCulture;
            if (formatProvider != null)
            {
                formatter = formatProvider;
            }

            formattedMessage = string.Format(formatProvider, message, args);

            string fullMessage = string.Format(formatter, "{0}, {1}, {2}: {3}", DateTime.Now, _consumerType.FullName, 
                prefix, formattedMessage);

            System.Console.WriteLine(fullMessage);
             
        }

        #endregion
    }
}
